package com.grademaster.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.grademaster.common.R;
import com.grademaster.dto.ScoreDto;
import com.grademaster.dto.ScoreManagePageDto;
import com.grademaster.dto.ScorePageDto;
import com.grademaster.entity.Courses;
import com.grademaster.entity.Scores;
import com.grademaster.mapper.ScoresMapper;
import com.grademaster.service.CoursesService;
import com.grademaster.service.ScoresService;
import com.grademaster.util.LoginUtil;
import com.grademaster.util.StringUtils;
import com.grademaster.vo.ScoreManageVO;
import com.grademaster.vo.ScorePageResultVO;
import com.grademaster.vo.ScoreStatisticsVO;
import com.grademaster.vo.ScoreVO;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;

/**
 * @author Administrator
 * @description 针对表【scores(成绩表)】的数据库操作Service实现
 * @createDate 2024-06-25 13:57:10
 */
@Service
public class ScoresServiceImpl extends ServiceImpl<ScoresMapper, Scores>
        implements ScoresService {

    @Autowired
    private ScoresMapper scoresMapper;
    @Autowired
    private CoursesService coursesService;

    /**
     * 分页查询成绩
     *
     * @param scorePageDto
     * @return
     */
    @Override
    public R getScoresList(ScorePageDto scorePageDto) {
        //判断是否登录
        StpUtil.isLogin();
        String userId = null;
        //判断是不是超级管理员，不是超级管理员只能查询自己的Id下的成绩
        if (!LoginUtil.isAdmin()) {
            userId = LoginUtil.getLoginUserId();
        }

        //获取分页列表
        List<ScoreVO> scores = scoresMapper.getScores(scorePageDto.getTermName(), scorePageDto.getCourseName()
                , scorePageDto.getVerification_status(), scorePageDto.getPage(), scorePageDto.getPageSize(), userId);

        //获取总记录数
        int count = scoresMapper.countScores(scorePageDto.getTermName(), scorePageDto.getCourseName(), scorePageDto.getVerification_status(), userId);

        //封装分页结果
        Page<ScoreVO> scoreVOPage = new Page<>(scorePageDto.getPage(), scorePageDto.getPageSize(), count);
        scoreVOPage.setRecords(scores);

        return R.success(scoreVOPage);
    }
    /**
     * 成绩导出2
     *
     * @param scorePageDto
     * @return
     */
    @Override
    public ResponseEntity exportExcel2(ScorePageDto scorePageDto) {
        //判断是否登录
        StpUtil.isLogin();
        String userId = null;
        //判断是不是超级管理员，不是超级管理员只能查询自己的Id下的成绩
        if (!LoginUtil.isAdmin()) {
            userId = LoginUtil.getLoginUserId();
        }

        //获取分页列表
        List<ScoreVO> scoreList = scoresMapper.getScores(scorePageDto.getTermName(), scorePageDto.getCourseName()
                , scorePageDto.getVerification_status(), 1, 2000, userId);
        Workbook workbook = new XSSFWorkbook();

        Sheet sheet = workbook.createSheet("Scores");

        // Create header row
        Row headerRow = sheet.createRow(0);
        String[] headers = {"成绩ID", "学期名称", "课程名称", "成绩", "成绩状态"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }

        // Create data rows
        int rowNum = 1;
        for (ScoreVO score : scoreList) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(score.getScoreId());
            row.createCell(1).setCellValue(score.getTermName());
            row.createCell(2).setCellValue(score.getCourseName());
            row.createCell(3).setCellValue(score.getScoreValue().doubleValue()); // Convert BigDecimal to double
            row.createCell(4).setCellValue(score.getVerificationStatus());
        }

        // Auto-size columns (optional)
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }

        // Write workbook to ByteArrayOutputStream
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // Create InputStreamResource to wrap ByteArrayInputStream
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        InputStreamResource resource = new InputStreamResource(inputStream);

        // Set response headers
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=scores.xlsx");

        // Return ResponseEntity with Excel file as body
        return ResponseEntity.ok()
                .headers(httpHeaders)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(resource);
    }

    /**
     * 成绩删除
     *
     * @param scoreId
     * @return
     */
    @Override
    public R deleteScore(String scoreId) {
        StpUtil.isLogin();
        //既不是成绩管理员也不是管理员
        if (!LoginUtil.isAdmin()){
            return R.error("权限不足");
        }
        String[] ids = scoreId.split(",");
        for (String id : ids) {
            this.removeById(id);
        }
        return R.success("删除成功");
    }

    /**
     * 分页查询教师管理成绩
     *
     * @param scoreManagePageDto
     * @return
     */
    @Override
    public R getScoresListTeacher(ScoreManagePageDto scoreManagePageDto) {
        //判断是否登录
        StpUtil.isLogin();
        String userId = null;
        //判断是不是超级管理员，不是超级管理员只能查询自己的Id下的成绩
        if (!LoginUtil.isAdmin()) {
            userId = LoginUtil.getLoginUserId();
        }
        if(StringUtils.isNotEmpty(scoreManagePageDto.getScoreValueOrder())&&StringUtils.isNotEmpty(scoreManagePageDto.getUsernameOrder())){
            return R.error("只能选择一个排序方式");
        }
        List<ScoreManageVO> voList = scoresMapper.selectScores(
                scoreManagePageDto.getUsername()
                , scoreManagePageDto.getName()
                , scoreManagePageDto.getClassName()
                , scoreManagePageDto.getTermName()
                , scoreManagePageDto.getCourseName()
                , scoreManagePageDto.getVerification_status()
                , scoreManagePageDto.getIsPass()
                , scoreManagePageDto.getPage()
                , scoreManagePageDto.getPageSize(),
                userId,
                scoreManagePageDto.getUsernameOrder(),
                scoreManagePageDto.getScoreValueOrder());

        //获取总记录数
        int count = scoresMapper.countselectScores(scoreManagePageDto.getUsername()
                , scoreManagePageDto.getName()
                , scoreManagePageDto.getClassName()
                , scoreManagePageDto.getTermName()
                , scoreManagePageDto.getCourseName()
                , scoreManagePageDto.getVerification_status()
                , scoreManagePageDto.getIsPass(),
                userId);

        ScorePageResultVO scorePageResultVO = new ScorePageResultVO();
        scorePageResultVO.setRecords(voList);
        scorePageResultVO.setTotal(count);
        ScoreStatisticsVO scoreStatistics = scoresMapper.getScoreStatistics(userId
                , scoreManagePageDto.getUsername()
                , scoreManagePageDto.getName()
                , scoreManagePageDto.getClassName()
                , scoreManagePageDto.getTermName()
                , scoreManagePageDto.getCourseName()
                , scoreManagePageDto.getVerification_status()
                , scoreManagePageDto.getIsPass());
        scorePageResultVO.setStatistics(scoreStatistics);
        return R.success(scorePageResultVO);
    }

    /**
     * 成绩送审
     *
     * @param scoreId
     * @return
     */
    @Override
    public R submitScore(String scoreId) {
        StpUtil.isLogin();
        String[] ids = scoreId.split(",");
        for (String id : ids) {
            Scores one = this.getOne(new LambdaQueryWrapper<Scores>().eq(Scores::getScoreId, id));
            //判断是不是管理员
            if (!LoginUtil.isAdmin()){
                //判断是否是该老师下的课程成绩
                Courses courses = coursesService.getOne(new LambdaQueryWrapper<Courses>().eq(Courses::getCourseId, one.getCourseId()));
                if (!LoginUtil.getLoginUserId().equals(courses.getTeacherId().toString())) {
                    return R.error("权限不足");
                }
            }
            //判断是否已经审核通过
            if (one.getVerificationStatus().equals("1")) {
                return R.error("该成绩已审核通过");
            }
            //判断是否正在审核
            if (one.getVerificationStatus().equals("3")) {
                return R.error("该成绩正在审核中");
            }
            one.setVerificationStatus(3);
            this.updateById(one);
        }
        return R.success("送审成功");
    }

    /**
     * 成绩修改
     *
     * @param scoreDto
     * @return
     */
    @Override
    public R updateScore(ScoreDto scoreDto) {
        StpUtil.isLogin();
        Scores one = this.getOne(new LambdaQueryWrapper<Scores>().eq(Scores::getScoreId, scoreDto.getScoreId()));

        //判断是不是管理员
        if(!LoginUtil.isAdmin()){
            //判断是否是该老师下的课程成绩
            Courses courses = coursesService.getOne(new LambdaQueryWrapper<Courses>().eq(Courses::getCourseId, one.getCourseId()));
            if (!LoginUtil.getLoginUserId().equals(courses.getTeacherId().toString())) {
                return R.error("权限不足");
            }
            //判断是否已经审核通过
            if (one.getVerificationStatus().equals("1")) {
                return R.error("该成绩已审核通过");
            }
            //判断是否正在审核
            if (one.getVerificationStatus().equals("3")) {
                return R.error("该成绩正在审核中");
            }
        }

        one.setScoreValue(scoreDto.getScoreValue());
        this.updateById(one);
        return R.success("修改成功");
    }

    /**
     * 成绩审核通过
     *
     * @param scoreId
     * @return
     */
    @Override
    public R passScore(String scoreId) {
        StpUtil.isLogin();
        String[] ids = scoreId.split(",");
        for (String id : ids) {
            Scores one = this.getOne(new LambdaQueryWrapper<Scores>().eq(Scores::getScoreId, id));
            //判断是不是管理员
            if (!LoginUtil.isAdmin()){
                //判断是否是该老师下的课程成绩
                Courses courses = coursesService.getOne(new LambdaQueryWrapper<Courses>().eq(Courses::getCourseId, one.getCourseId()));
                if (!LoginUtil.getLoginUserId().equals(courses.getTeacherId().toString())) {
                    return R.error("权限不足");
                }
            }
            //判断是否在审核中
            if (one.getVerificationStatus().equals("3")) {
                return R.error("该成绩未在审核中");
            }
            one.setVerificationStatus(1);
            this.updateById(one);
        }
        return R.success("审核通过成功");
    }

    /**
     * 成绩审核不通过
     *
     * @param scoreId
     * @return
     */
    @Override
    public R noPassScore(String scoreId) {
        StpUtil.isLogin();
        String[] ids = scoreId.split(",");
        for (String id : ids) {
            Scores one = this.getOne(new LambdaQueryWrapper<Scores>().eq(Scores::getScoreId, id));
            //判断是不是管理员
            if (!LoginUtil.isAdmin()){
                //判断是否是该老师下的课程成绩
                Courses courses = coursesService.getOne(new LambdaQueryWrapper<Courses>().eq(Courses::getCourseId, one.getCourseId()));
                if (!LoginUtil.getLoginUserId().equals(courses.getTeacherId().toString())) {
                    return R.error("权限不足");
                }
            }
            //判断是否在审核中
            if (one.getVerificationStatus().equals("3")) {
                return R.error("该成绩未在审核中");
            }
            one.setVerificationStatus(2);
            this.updateById(one);
        }
        return R.success("审核未通过成功");
    }

    /**
     * 成绩导出
     *
     * @param scoreManagePageDto
     * @return
     */
    @Override
    public ResponseEntity exportExcel(ScoreManagePageDto scoreManagePageDto) {
        // 获取成绩数据
        //判断是否登录
        StpUtil.isLogin();
        String userId = null;
        //判断是不是超级管理员，不是超级管理员只能查询自己的Id下的成绩
        if (!LoginUtil.isAdmin()) {
            userId = LoginUtil.getLoginUserId();
        }
        if(StringUtils.isNotEmpty(scoreManagePageDto.getScoreValueOrder())&&StringUtils.isNotEmpty(scoreManagePageDto.getUsernameOrder())){
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
        List<ScoreManageVO> scoreList = scoresMapper.selectScores(
                scoreManagePageDto.getUsername()
                , scoreManagePageDto.getName()
                , scoreManagePageDto.getClassName()
                , scoreManagePageDto.getTermName()
                , scoreManagePageDto.getCourseName()
                , scoreManagePageDto.getVerification_status()
                , scoreManagePageDto.getIsPass()
                ,1
                ,2000
                ,userId,
                scoreManagePageDto.getUsernameOrder(),
                scoreManagePageDto.getScoreValueOrder());

        // 创建工作簿
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("成绩管理");

        // 创建表头
        Row headerRow = sheet.createRow(0);
        String[] headers = {"成绩ID", "用户名", "姓名", "班级名称", "学期名称", "课程名称", "成绩", "成绩状态"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }

        // 写入数据
        int rowNum = 1;
        for (ScoreManageVO score : scoreList) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(score.getScoreId());
            row.createCell(1).setCellValue(score.getUsername());
            row.createCell(2).setCellValue(score.getName());
            row.createCell(3).setCellValue(score.getClassName());
            row.createCell(4).setCellValue(score.getTermName());
            row.createCell(5).setCellValue(score.getCourseName());
            row.createCell(6).setCellValue(score.getScoreValue().doubleValue()); // 将 BigDecimal 转换为 double
            row.createCell(7).setCellValue(score.getVerificationStatus());
        }

        // 将Workbook写入ByteArrayOutputStream
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            workbook.write(outputStream);
        } catch (IOException e) {
            log.error("导出Excel时发生IO异常", e);
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                log.error("关闭Workbook或OutputStream时发生异常", e);
            }
        }

        // 创建一个InputStreamResource以包装ByteArrayInputStream
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        InputStreamResource resource = new InputStreamResource(inputStream);

        // 设置响应头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=scores.xlsx");


        // 返回ResponseEntity
        return ResponseEntity.ok()
                .headers(httpHeaders)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(resource);
    }


}




